#include "esp_log.h"
#include "string.h"
#include "task_info.h"

// 定义日志标签
static const char *TAG = "TaskStats";

// 更新任务信息结构体
void task_info_update(TaskInfo *task_info_array) {
    TaskStatus_t *pxTaskStatusArray;
    volatile UBaseType_t uxArraySize, x;
    uint32_t ulTotalRunTime = 0;
    uint32_t ulTaskRunTime[configMAX_TASK_NAME_LEN] = {0};

    // 获取系统中任务的数量
    uxArraySize = uxTaskGetNumberOfTasks();

    // 为每个任务的状态信息分配内存
    pxTaskStatusArray = (TaskStatus_t *)pvPortMalloc(uxArraySize * sizeof(TaskStatus_t));

    if (pxTaskStatusArray != NULL) {
        // 获取每个任务的状态信息和总运行时间
        uxTaskGetSystemState(pxTaskStatusArray, uxArraySize, NULL);

        // 统计所有任务的运行时间
        for (x = 0; x < uxArraySize; x++) {
            ulTotalRunTime += pxTaskStatusArray[x].ulRunTimeCounter;
            ulTaskRunTime[x] = pxTaskStatusArray[x].ulRunTimeCounter;
        }

        // 更新任务信息结构体
        for (x = 0; x < uxArraySize; x++) {
            task_info_array[x].task_id = pxTaskStatusArray[x].xHandle;
            strncpy(task_info_array[x].task_name, pxTaskStatusArray[x].pcTaskName, configMAX_TASK_NAME_LEN - 1);
            task_info_array[x].task_name[configMAX_TASK_NAME_LEN - 1] = '\0';
            task_info_array[x].core_id = pxTaskStatusArray[x].xCoreID;
            if (ulTotalRunTime > 0) {
                task_info_array[x].cpu_usage = ((double)ulTaskRunTime[x] / (double)ulTotalRunTime) * 100.0;
            } else {
                task_info_array[x].cpu_usage = 0.0;
            }
            task_info_array[x].priority = pxTaskStatusArray[x].uxCurrentPriority;  // 获取任务优先级
            task_info_array[x].task_state = pxTaskStatusArray[x].eCurrentState;
        }

        // 释放分配的内存
        vPortFree(pxTaskStatusArray);
    }
}

// 打印任务信息到内存
void task_info_print_to_memory(TaskInfo *task_info_array, UBaseType_t array_size, char *buffer, size_t buffer_size) {
    size_t offset = 0;

    // 打印表头，将优先级放到 task_state 前面
    offset += snprintf(buffer + offset, buffer_size - offset, "| %-16s | %-6s | %-4s | %-5s | %-8s |\n",
                       "Task Name", "Usage", "Prio", "State", "Core");
    // 打印分隔线
    double total_usage = 0;

    // 打印每个任务的信息，将优先级放到 task_state 前面
    for (UBaseType_t x = 0; x < array_size; x++) {
        offset += snprintf(buffer + offset, buffer_size - offset, "| %-16s | %-5.2f%% | %-4u | %-5d | %-8x |\n",
                           task_info_array[x].task_name,
                           task_info_array[x].cpu_usage,
                           task_info_array[x].priority,
                           task_info_array[x].task_state,
                           task_info_array[x].core_id);
        // 打印分隔线
        total_usage += task_info_array[x].cpu_usage;
    }
}

// 打印任务信息到内存
void task_info_print_to_memory2(TaskInfo *task_info_array, UBaseType_t array_size, char *buffer, size_t buffer_size) {
    size_t offset = 0;

    // 打印表头，将优先级放到 task_state 前面
    offset += snprintf(buffer + offset, buffer_size - offset, "| %-10s | %-16s | %-6s | %-4s | %-5s | %-8s |\n",
                       "Task ID", "Task Name", "Usage", "Prio", "State", "Core");
    // 打印分隔线
    // offset += snprintf(buffer + offset, buffer_size - offset, "|------------|------------------|--------|-------|----------|\n");

    double total_usage = 0;

    // 打印每个任务的信息，将优先级放到 task_state 前面
    for (UBaseType_t x = 0; x < array_size; x++) {
        offset += snprintf(buffer + offset, buffer_size - offset, "| %-10p | %-16s | %-5.2f%% | %-4u | %-5d | %-8x |\n",
                           task_info_array[x].task_id,
                           task_info_array[x].task_name,
                           task_info_array[x].cpu_usage,
                           task_info_array[x].priority,
                           task_info_array[x].task_state,
                           task_info_array[x].core_id);
        // 打印分隔线
        // offset += snprintf(buffer + offset, buffer_size - offset, "|------------|------------------|--------|-------|----------|\n");
        total_usage += task_info_array[x].cpu_usage;
    }

    // 打印所有任务的总 CPU 使用率
    snprintf(buffer + offset, buffer_size - offset, "Total CPU Usage: %.2f%%\n", total_usage);
}

void task_info_print() {
    UBaseType_t uxArraySize = uxTaskGetNumberOfTasks();
    TaskInfo *task_info_array = (TaskInfo *)pvPortMalloc(uxArraySize * sizeof(TaskInfo));
    char buffer[2048];
    if (task_info_array != NULL) {
        // 更新任务信息
        task_info_update(task_info_array);

        // 打印任务信息
        task_info_print_to_memory(task_info_array, uxArraySize, buffer, 2048);
        printf("\n%s\n", buffer);

        // 释放分配的内存
        vPortFree(task_info_array);
    }
}

// 任务 1：CPU 密集型任务
void cpu_intensive_task(void *pvParameters) {
    while (1) {
        for (volatile int i = 0; i < 1000000; i++);
        vTaskDelay(pdMS_TO_TICKS(10));
    }
}

// 任务 2：IO 密集型任务
void io_intensive_task(void *pvParameters) {
    while (1) {
        vTaskDelay(pdMS_TO_TICKS(100));
    }
}

// 任务 3：计算密集型任务
void compute_intensive_task(void *pvParameters) {
    volatile int result = 0;
    while (1) {
        for (int i = 0; i < 1000; i++) {
            result += i * i;
        }
        vTaskDelay(pdMS_TO_TICKS(10));
    }
}

void task_info_test() {
    // 创建任务，不指定 CPU 核心
    xTaskCreate(cpu_intensive_task, "CPU_Intensive", 2048, NULL, 1, NULL);
    xTaskCreate(io_intensive_task, "IO_Intensive", 2048, NULL, 1, NULL);
    xTaskCreate(compute_intensive_task, "Compute_Intensive", 2048, NULL, 1, NULL);

    while (1) {
        // 运行一段时间，让任务有足够的时间执行
        vTaskDelay(pdMS_TO_TICKS(5000));

        UBaseType_t uxArraySize = uxTaskGetNumberOfTasks();
        TaskInfo *task_info_array = (TaskInfo *)pvPortMalloc(uxArraySize * sizeof(TaskInfo));

        if (task_info_array != NULL) {
            // 更新任务信息
            task_info_update(task_info_array);
            // 打印任务信息
            task_info_print_(task_info_array, uxArraySize);

            // 释放分配的内存
            vPortFree(task_info_array);
        }
    }

    // 可以在这里添加其他任务或逻辑
    vTaskDelete(NULL);
}